#include "mex.h"
#include <stdio.h>
#include <stdlib.h>

enum {messageIdx                  = 0, /* input code */
      polyIdx,
      messageSizeIdx,
      polySizeIdx
      };
      
#define messageArg                 (prhs[messageIdx])
#define polyArg                    (prhs[polyIdx])
#define msgSizeArg                 (prhs[messageSizeIdx])
#define polySizeArg                (prhs[polySizeIdx])

#define output                     (plhs[0])


static void CheckParameters(int nlhs,       mxArray *plhs[],
                            int nrhs, const mxArray *prhs[])
{
    const char  *msg   = NULL;

    /* Check number of parameters */
    if (!(nrhs == 4)) {
        msg = "Invalid number of input arguments. This function only works"
        "with 4 input arguments.";
        goto EXIT_POINT;
    }
    if(nlhs >= 2){
        msg = "Invalid number of output arguments. This function only works"
        "with 1 output argument.";
        goto EXIT_POINT;
    }


EXIT_POINT:
    if(msg != NULL){
        mexErrMsgTxt(msg);
    }
}

static void CRC(int nlhs,       mxArray *plhs[],
                       int nrhs, const mxArray *prhs[])
{
   double *message , *poly, *out;
   int msgSize, polySize, counter, aux;
   
   message = mxGetPr(messageArg);
   poly = mxGetPr(polyArg);

   msgSize = mxGetScalar(msgSizeArg);
   polySize = mxGetScalar(polySizeArg);
   
   output = mxCreateDoubleMatrix(1,polySize-1,mxREAL);
   out = mxGetPr(output);

   for (counter = 0; counter < msgSize - polySize + 1  ; counter++){
       
       double *msgPos;
       double auxiliar;
       int bit;
       
       msgPos = message + counter;
       auxiliar = message[counter];
       
       if (auxiliar == 1.0){
           
           for(bit = 0; bit < polySize; bit++){
               
               double sum;
               
               sum = message[bit+counter] + poly[bit];
               
               if ( ((int)sum % 2) == 0.0){
                   
                   message[bit+counter] = 0.0;
                   
               } else {
                   
                   message[bit+counter] = 1.0;
               }
               
           }
           
       } 
       else continue;
           
       
   } 
   

   aux = 0;
    for(counter = msgSize - polySize + 1; counter < msgSize; counter++){
        
        out[aux] = message[counter]; 
        aux++;
         
    }
}

void mexFunction(int nlhs,       mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    CheckParameters(nlhs, plhs, nrhs, prhs);
    CRC(nlhs,plhs, nrhs,prhs);
    

}